#!/usr/bin/env python
# encoding: utf-8
import os
import sys
import platform

name = 'project'
CSDK_ROOT = os.getenv('RDA8910_ROOT')
gcc_root = os.path.join(CSDK_ROOT, "prebuilts/win32/gcc-arm-none-eabi")

if not CSDK_ROOT:
  print('RDA8910_ROOT not set.')
  sys.exit(1)

GCC_INSTALL_PATH = os.path.join(gcc_root, 'bin')
SDK_PATH = CSDK_ROOT

PREFIX="arm-none-eabi-"
ARMCC=PREFIX+'gcc'
ARMAS=PREFIX+'gcc'
ARMAR=PREFIX+'ar'
ARMLINK=PREFIX+'gcc'
ARMSIZE=PREFIX+'size'
ARMOBJDUMP=PREFIX+'objdump'
ARMOBJCOPY=PREFIX+'objcopy'
INCLUDES = [
  os.path.join(SDK_PATH, 'core/iot_SDK_720U/memd'),
  os.path.join(SDK_PATH, 'components/include'),
  os.path.join(SDK_PATH, 'components/openat_inc'),
  os.path.join(SDK_PATH, 'components/newlib/include'),
  os.path.join(SDK_PATH, 'components/ril/inc'),
  os.path.join(SDK_PATH, 'api/include'),
]

flags="""
-DCSDK_PRO=CSDK -DCSDK_VER=\"1.0.0\" -D_WINSOCKAPI_
-std=gnu11   -mcpu=cortex-a5 -mtune=generic-armv7-a
-mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mno-unaligned-access
-g -Os -Wall -fno-strict-aliasing -ffunction-sections
-fdata-sections
"""
#-fstrict-aliasing -fomit-frame-pointer -flto -fno-asynchronous-unwind-tables -fno-stack-protector -fno-stack-check

CFLAGS=flags.strip().replace('\n', ' ').split(' ')

LINKFLAGS=[
  '-std=gnu11',
  '-Wl,-T$TARGET.dir/app_flashimg.sld',
  '-Wl,-Map=$TARGET.dir/output.map',
  '-nostdlib',
  '-Wl,--gc-sections',
]

DEFINES = []

LIBS=[
  File(os.path.abspath(os.path.join(SDK_PATH, 'components/newlib/armca5/libc.a'))),
  File(os.path.abspath(os.path.join(SDK_PATH, 'components/newlib/armca5/libm.a'))),
  File(os.path.abspath(os.path.join(SDK_PATH, 'components/newlib/armca5/libc.a'))),
  File(os.path.abspath(os.path.join(GCC_INSTALL_PATH, '../lib/gcc/arm-none-eabi/7.2.1/thumb/v7-ar/fpv3/hard/libgcc.a'))),
]

env=Environment(
  AS=ARMAS,
  CC=ARMCC,
  AR=ARMAR,
  LINK=ARMLINK,
  CFLAGS=CFLAGS,
  LINKFLAGS=LINKFLAGS,
  CPPDEFINES=DEFINES,
  CPPPATH=INCLUDES,
  LIBS=LIBS,
  TOOLS=["mingw"]
)
env.PrependENVPath('PATH', GCC_INSTALL_PATH)
env.PrependENVPath('PATH', os.path.abspath(os.path.join(SDK_PATH, 'tools/win32')))
env.PrependENVPath('PATH', os.path.abspath(os.path.join(SDK_PATH, 'prebuilts/win32/python3')))

dtools = 'dtools.exe'
python3 = 'python3.exe'
pacgen = os.path.join(SDK_PATH, 'tools/pacgen.py')

# 执行8910固件dump过程
pac_dump_action='%s pacdump $SOURCES $TARGET' % dtools
pac_dump_src = File(os.path.join(SDK_PATH, 'core/iot_SDK_720U/CSDK_RDA8910.pac'))
pac_dump_dst = 'out/oldpac'
env.Command(pac_dump_dst, pac_dump_src, pac_dump_action, target_factory=Dir)

project_erase_json = 'appimg_flash_delete.json'
project_app_json = 'Air720U_CSDK_%s_APP.json' % name

cfg_init_action = '%s %s cfg-init --pname UIX8910_MODEM --palias APPIMG --pversion "8910 MODULE" --version "BP_R1.0.0" --flashtype 1 $TARGET' % (python3, pacgen)
cfg_host_fdl_action = '%s %s cfg-host-fdl -a 0x810000 -s 0x8000 -p $SOURCE.abspath/fdl1.sign.img $TARGET' % (python3, pacgen)
cfg_fdl2_action = '%s %s cfg-fdl2 -a 0x818000 -s 0x10000 -p $SOURCE.abspath/fdl2.sign.img $TARGET' % (python3, pacgen)
cfg_erase_flash_action = '%s %s cfg-erase-flash -i ERASE_APPIMG -a 0x60160000 -s 0x1E0000 $TARGET' % (python3, pacgen)
cfg_image = '%s %s cfg-image -i APPIMG -a 0x60160000 -s 0x1E0000 -p $TARGET.dir/%s.img $TARGET' % (python3, pacgen, name)
dep_gen_action = '%s %s dep-gen --base %s $TARGET' % (python3, pacgen, SDK_PATH)

erase_flash_json = ' && '.join([cfg_init_action, cfg_host_fdl_action, cfg_fdl2_action, cfg_erase_flash_action, dep_gen_action])
env.Command(project_erase_json, pac_dump_dst, erase_flash_json, source_factory=Dir)

app_img_json = ' && '.join([cfg_init_action, cfg_host_fdl_action, cfg_fdl2_action, cfg_image, dep_gen_action])
env.Command(project_app_json, pac_dump_dst, app_img_json, source_factory=Dir)

project_app_all_json = 'Air720U_CSDK_%s.json' % name
app_all_img_cmds = [
  '%s %s cfg-init --pname UIX8910_MODEM --palias APPIMG --pversion "8910 MODULE" --version "BP_R1.0.0" --flashtype 1 $TARGET ' % (python3, pacgen),
  '%s %s cfg-host-fdl -a 0x810000 -s 0x8000 -p $SOURCE.abspath/fdl1.sign.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-fdl2 -a 0x818000 -s 0x10000 -p $SOURCE.abspath/fdl2.sign.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-nvitem -n Calibration -i 0xFFFFFFFF --use 1 --replace 0 --continue 0 --backup 1 $TARGET ' % (python3, pacgen),
  '%s %s cfg-nvitem -n "GSM Calibration" -i 0x26d --use 1 --replace 0 --continue 1 --backup 1 $TARGET ' % (python3, pacgen),
  '%s %s cfg-nvitem -n "LTE Calibration" -i 0x26e --use 1 --replace 0 --continue 0 --backup 1 $TARGET ' % (python3, pacgen),
  '%s %s cfg-nvitem -n IMEI -i 0xFFFFFFFF --use 1 --replace 0 --continue 0 --backup 1 $TARGET ' % (python3, pacgen),
  '%s %s cfg-phase-check $TARGET ' % (python3, pacgen),
  '%s %s cfg-image -i BOOTLOADER -a 0x60000000 -s 0x10000 -p $SOURCE.abspath/boot.sign.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-image -i AP -a 0x60010000 -s 0x150000 -p $SOURCE.abspath/8915DM_cat1_CSDK.sign.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-image -i PS -a 0x604a0000 -s 0x340000 -p $SOURCE.abspath/cat1_64X128_UIS8915DM_BB_RF_SingleSim.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-image -i APPIMG -a 0x60160000 -s 0x1E0000 -p $TARGET.dir/%s.img $TARGET ' % (python3, pacgen, name),
  '%s %s cfg-image -i SFFS -a 0x60340000 -s 0x160000 -p $SOURCE.abspath/sffs.img $TARGET ' % (python3, pacgen),
  '%s %s cfg-erase-flash -i FLASH -a 0xFE000001 -s 0 $TARGET ' % (python3, pacgen),
  '%s %s cfg-nv -s 0x20000 -p $SOURCE.abspath/cat1_64X128_UIS8915DM_BB_RF_SingleSim_nvitem.bin $TARGET ' % (python3, pacgen),
  '%s %s dep-gen --base %s $TARGET' % (python3, pacgen, SDK_PATH),  
]
env.Command(project_app_all_json, pac_dump_dst, ' && '.join(app_all_img_cmds), source_factory=Dir)

lib_ril = env.StaticLibrary(
  'ril',
  [
    File(os.path.join(SDK_PATH, 'components/ril/src/at_process.c')),
    File(os.path.join(SDK_PATH, 'components/ril/src/at_tok.c')),
    File(os.path.join(SDK_PATH, 'components/ril/src/ril_pal.c')),
  ]
)
lib_api = env.StaticLibrary('api', Glob(os.path.join(SDK_PATH, 'api/src') + '/*.c'))
core_stub = File(os.path.join(SDK_PATH, 'core/iot_SDK_720U/lib/core_stub.o'))

link_file_cmd = '%s -std=gnu11 -mcpu=cortex-a5 -mtune=generic-armv7-a -mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mno-unaligned-access -g -Os -Wall -fno-strict-aliasing -ffunction-sections -fdata-sections -E -P -x c -I %s -o $TARGET -c $SOURCES'
link_file_action = link_file_cmd % (ARMCC, os.path.join(SDK_PATH, 'core/iot_SDK_720U/memd'))
env['BUILDERS']['LinkScript'] = Builder(action=link_file_action, suffix=".sld", src_suffix='.ld')

link_source_file = os.path.join(SDK_PATH, 'ldscripts/app_flashimg.ld')
link_ld_file = 'app_flashimg.sld'
link_result = env.LinkScript(target=link_ld_file, source=link_source_file)

# option
AddOption(
    '--vscode',
    dest='vscode',
    action='store_true',
    metavar='EXPORT',
    help='export vscode project settings',
)

import json
import stat
def check_vscode_dir(d):
  try:
    res = os.stat(d)
    if not stat.S_ISDIR(res.st_mode):
      msg = '%s is not a dir, please remove it first.' % d
      print(d)
      raise Exception(d)
  except Exception as e:
    os.mkdir(d)

def vscode_project_action(source, target, env):
  print(type(env))
  print(env)
  print(dir(env))

  args = {
    'name': name,
    'intelliSenseMode': 'gcc-x64',
    'includePath': INCLUDES,
    'defines': [],
    'forcedInclude': [],
    'compilePath': os.path.join(GCC_INSTALL_PATH, 'arm-none-eabi-gcc.exe'),
    'cStandard': 'c99',
    'cppStandard': 'c++11',
    'compileCommands': 'scons',
    'browse': {
      'path': [],
      'limitSymbolsToIncludedHeaders': True,
      'databaseFilename': '',
    }
  }
  out = {
    'env': {},
    'configurations': [args],
    'version': 4,
  }
  check_vscode_dir('.vscode')
  with open('.vscode/c_cpp_properties.json', 'wt') as fout:
    fout.write(json.dumps(out, indent=4))
  print('vscode project generate completed.')

env['BUILDERS']['Vscode'] = Builder(action=vscode_project_action)

# VariantDir('build')
Export('env')
Export('SDK_PATH')
Export('CSDK_ROOT')
Export('INCLUDES')

lib_app = env.SConscript('app/Sconstruct')

elftarget='%s.elf' % name
elf_result = env.Program(source=[core_stub, lib_app, lib_api, lib_ril], target=elftarget)
env.Depends(elf_result, link_result)

# 固件生成步骤
# dtools mkappimg E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello.elf E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello.img
mkappimg = '%s mkappimg $SOURCES $TARGET' % dtools
env['BUILDERS']['MkAppImg'] = Builder(action=mkappimg, suffix=".img", src_suffix='.elf')
imgtarget = '%s.img' % name
env.MkAppImg(source=elftarget, target=imgtarget)

# python3 E:/dev/Luat_CSDK_Air724U/tools/pacgen.py pac-gen E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello_APP.json E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello_APP.pac
app_json = os.path.join(SDK_PATH)
mk_app_pac = '%s %s pac-gen $TARGET.dir/%s $TARGET' % (python3, pacgen, project_app_json)
app_pac_filename = 'Air720U_CSDK_%s_APP.pac' % name
env['BUILDERS']['MkAppPac'] = Builder(action=mk_app_pac, suffix='.pac', src_suffix='.img')
env.MkAppPac(source=imgtarget, target=app_pac_filename)

# python3 E:/dev/Luat_CSDK_Air724U/tools/pacgen.py pac-gen E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello.json E:/dev/Luat_CSDK_Air724U/out/hello_debug/hex/Air720U_CSDK_demo_hello.pac
mk_all_pac = '%s %s pac-gen $TARGET.dir/%s $TARGET' % (python3, pacgen, project_app_all_json)
all_pac_filename = 'Air720U_CSDK_%s.pac' % name
env['BUILDERS']['MkAllPac'] = Builder(action=mk_all_pac, suffix='.pac', src_suffix='.img')
env.MkAllPac(source=imgtarget, target=all_pac_filename)

# copy files
# python3 E:/dev/Luat_CSDK_Air724U/tools/gdbComGen.py E:/dev/Luat_CSDK_Air724U /hex/Air720U_CSDK_demo_hello_map/app.elf"
# env.Command()

if GetOption('vscode') == True:
    env.Vscode(source=[], target='.vscode')

